﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using PinCity.Models.Repositories;

namespace PinCity.Models.Accounts
{
    /// <summary>
    /// Role provider, that relies on fluent repositories.
    /// Not fully implemented yet.
    /// </summary>
    public class FluentRoleProvider : RoleProvider
    {
        private readonly RolesRepository _roles = new RolesRepository();
        private readonly UsersRepository _users = new UsersRepository();
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(typeof(FluentRoleProvider));

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override string ApplicationName
        {
            get
            {
                return "PinCity";
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override void CreateRole(string roleName)
        {
            logger.Debug("Role creation invoked for role " + roleName + ".");
            Role tmp = new Role(roleName);
            if (_roles.GetRoleByName(roleName) == null)
            {
                _roles.SaveOrUpdate(tmp);
                logger.Info("Created role " + tmp + ".");
            }
            else
            {
                logger.Warn("Role with such name already exist. Skip operation.");
            }
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            bool result = false;
            Role roleToDelete = _roles.GetRoleByName(roleName);
            if (roleToDelete != null)
            {
                if (!roleToDelete.Users.Any())
                {
                    _roles.Delete(roleToDelete);
                    result = true;
                }
            }
            return result;
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            return new string[] { "Users in role here" };
            //throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            string[] result = new string[] { "No roles found" };
            IList<Role> roles = _roles.GetAll();
            if (roles != null)
            {
                result = (from r in roles select r.Name).ToArray();
            }
            return result;
        }

        public override string[] GetRolesForUser(string username)
        {
            string[] result = new string[] { "No roles found!" };
            User user = _users.GetUserByName(username);
            if (user == null || user.Role == null)
            {

            }
            else
            {
                result = new string[] { user.Role.Name };
            }
            return result;
        }

        public override string[] GetUsersInRole(string roleName)
        {
            string[] result = new string[] { "No users found!" };
            Role role = _roles.GetRoleByName(roleName);
            if (role != null && role.Users != null && role.Users.Any())
            {
                var users = from u in role.Users
                            select u.Login;
                result = users.ToArray();
            }
            return result;
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            bool result = false;
            Role role = _roles.GetRoleByName(roleName);
            if (role != null && role.Users.Any(u=>u.Login.Equals(username)))
            {
                result = true;
            }
            return result;
        }

        /// <summary>
        /// Not implemented yet.
        /// </summary>
        /// <param name="usernames"></param>
        /// <param name="roleNames"></param>
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            //throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            return _roles.GetRoleByName(roleName) != null;
        }
    }
}